# GF_PY3_CLASS_Finance_Stock_Matplotlib_3_7_x.py
# Create By GF 2024-01-22 18:16

import matplotlib.pyplot as plt

# ##################################################

class Finance_Stock_Matplotlib_3_7_x(object):

    def __init__(self):
    
        self.README_LIST = [
            "Example:\n",
            "\n",
            ">>> import matplotlib.pyplot as plt\n",
            ">>>\n",
            ">>> fig = plt.figure(figsize=(16, 9), dpi=96)\n",
            ">>> grid = plt.GridSpec(4, 1, figure=fig)\n",
            ">>> ax = plt.subplot(grid[0:3])\n",
            "...\n",
            ">>> FSM37X = Finance_Stock_Matplotlib_3_7_x()\n",
            ">>> FSM37X.Candlestick_Chart(ax, df, 'idx', 'open', 'high', 'low', 'close', 'change')\n",
            "...\n"
        ]
        self.README = str('').join(self.README_LIST)
        
        # 16 进制色值信息:
        # - #FF4500 - 红色 (适用于 Candlestick Chart)
        # - #228B22 - 绿色 (适用于 Candlestick Chart)

    def Annotate_Upward(self, Axis, Pandas_DataFrame, X_Field, Y_Field, Text:str=''):
    
        # 注解 (Annotate) Example:
        #
        # >>> import matplotlib.pyplot as plt
        # >>>
        # >>> x = [1, 2, 3, 4, 5]
        # >>> y = [2, 3, 5, 7, 11]
        # >>>
        # >>> plt.plot(x, y) # 创建图表
        # >>> arrow_properties = dict(facecolor='black', shrink=0.05)
        # >>> plt.annotate('', xy=(2, 5), xytext=(2, 3), arrowprops=arrow_properties) # 在第 3 个数据点处添加箭头
        # >>> plt.show() # 显示图表
        #
        # Params:
        # - xy 定义箭头的起始位置
        # - xytext 定义箭头的文本位置
        # - arrowprops 定制箭头的样式 (颜色, 宽度和大小等)
        
        df = Pandas_DataFrame
        # ..........................................
        Arrow_Properties = dict(arrowstyle="->", facecolor='black')
        # ..........................................
        Difference_Between_Max_and_Min = df[Y_Field].max() - df[Y_Field].min()
        # ..........................................
        for x0, y0 in zip(df[X_Field], df[Y_Field]):
            head_offset = Difference_Between_Max_and_Min * 0.01  # 头端偏移
            tail_offset = Difference_Between_Max_and_Min * 0.08  # 尾端偏移
            Axis.annotate(Text, xy=(x0, y0 - head_offset), xytext=(x0, y0 - tail_offset), arrowprops=Arrow_Properties)

    def Annotate_Downward(self, Axis, Pandas_DataFrame, X_Field, Y_Field, Text:str=''):
        
        df = Pandas_DataFrame
        # ..........................................
        Arrow_Properties = dict(arrowstyle="->", facecolor='black')
        # ..........................................
        Difference_Between_Max_and_Min = df[Y_Field].max() - df[Y_Field].min()
        # ..........................................
        for x0, y0 in zip(df[X_Field], df[Y_Field]):
            head_offset = Difference_Between_Max_and_Min * 0.01  # 头端偏移
            tail_offset = Difference_Between_Max_and_Min * 0.08  # 尾端偏移
            Axis.annotate(Text, xy=(x0, y0 + head_offset), xytext=(x0, y0 + tail_offset), arrowprops=Arrow_Properties)

    def Candlestick_Chart(self, Axis, Pandas_DataFrame, Index_Field, Open_Field, High_Field, Low_Field, Close_Field, Change_Field):

        PandasDF = Pandas_DataFrame
        # ..........................................
        # 上涨蜡烛线绘图数据
        df = PandasDF[PandasDF["change"] >= 0.0].copy()
        df["rise_candle_bottom"] = df[Open_Field]
        df["rise_candle_height"] = df[Close_Field] - df[Open_Field]
        # ..........................................
        Axis.bar(x=df[Index_Field], height=df["rise_candle_height"], width=0.6, bottom=df["rise_candle_bottom"], color="#FF4500")
        Axis.vlines(x=df[Index_Field], ymin=df[Low_Field], ymax=df[High_Field], colors="#FF4500", linewidth=1)
        # ..........................................
        # 下跌蜡烛线绘图数据
        df = PandasDF[PandasDF["change"] < 0.0].copy()
        df["fall_candle_bottom"] = df[Close_Field]
        df["fall_candle_height"] = df[Open_Field] - df[Close_Field]
        # ..........................................
        Axis.bar(x=df[Index_Field], height=df["fall_candle_height"], width=0.6, bottom=df["fall_candle_bottom"], color="#228B22")
        Axis.vlines(x=df[Index_Field], ymin=df[Low_Field], ymax=df[High_Field], colors="#228B22", linewidth=1)

# EOF Signed by GF.
